package next.fire.spinus.logx.provider.aliyun.client;

import next.fire.spinus.logx.utils.codec.HmacSHA1;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

/**
 * Created by daibing on 2019/3/4.
 */
public class AliyunHelper {

    private static final String HTTP_PROTOCOL_END = "://";

    private static final String NEW_LINE = "\n";

    public static final String RFC_2616_DAY_TIME_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z";

    public static String getGmtString(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(RFC_2616_DAY_TIME_FORMAT, Locale.US);
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return dateFormat.format(date);
    }

    public static String getProtocol(String url) {
        int index = url.indexOf(HTTP_PROTOCOL_END);
        if (index > 0) {
            return url.substring(0, index + HTTP_PROTOCOL_END.length());
        } else {
            throw new RuntimeException("Does not found protocol for url: " + url);
        }
    }

    /**
     * @return 带resourceName的子域名
     */
    public static String getResourceHost(String url, String resourceName) {
        int index = url.indexOf(HTTP_PROTOCOL_END);
        String host = null;
        if (index > 0) {
            host = url.substring(index + HTTP_PROTOCOL_END.length());
        } else {
            host = url;
        }
        return isEmpty(resourceName) ? host : resourceName + "." + host;
    }

    public static String getCanonicalizedResource(String uri, Map<String, String> queryString) {
        if (queryString == null || queryString.size() <= 0) {
            return uri;
        }
        StringBuilder sb = new StringBuilder(uri + "?");
        for (Map.Entry<String, String> entry : queryString.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    public static String getCanonicalizedHeaders(Map<String, String> header, String... includePrefix) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : header.entrySet()) {
            String lowerKey = entry.getKey().toLowerCase().trim();
            for (String prefix : includePrefix) {
                if (lowerKey.startsWith(prefix.toLowerCase())) {
                    sb.append(lowerKey).append(":").append(entry.getValue().trim()).append(NEW_LINE);
                    break;
                }
            }
        }
        if (sb.length() > 1) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }

    public static String sign(String method, String contentMd5, String contentType, String gmtDateString,
                              String canonicalizedHeaders, String canonicalizedResource, String accessKeySecret) {
        String raw = method + NEW_LINE
                + contentMd5 + NEW_LINE
                + contentType + NEW_LINE
                + gmtDateString + NEW_LINE
                + (isEmpty(canonicalizedHeaders) ? "" : canonicalizedHeaders + NEW_LINE)
                + canonicalizedResource;
        return HmacSHA1.genHMACBase64Encoded(raw, accessKeySecret);
    }

    public static String getAuthorization(String prefix, String accessKeyId, String signature) {
        return prefix + accessKeyId + ":" + signature;
    }

    private static boolean isEmpty(String str) {
        return str == null || str.isEmpty();
    }
}
